package eu.jk.config;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.LinkedList;
import java.util.List;
import eu.jk.config.PathResolver.Token;

public class PlainTextEngine extends ConfigEngine {

	Config interConfig = null;
	
	String currentPath = null;
	
	@Override
	public void init(Reader reader) throws ConfigException {
		interConfig = Config.load(reader, "plain");
	}

	@Override
	public void init(String path, String encoding) throws ConfigException {
		try {
			init(new InputStreamReader(new FileInputStream(new File(path)),
					encoding));
		} catch (FileNotFoundException e) {
			throw new ConfigException(e);
		} catch (UnsupportedEncodingException e) {
			throw new ConfigException(e);
		}
	}

	@Override
	public void locate(String path) throws ConfigException {
		this.currentPath = path;
	}

	@Override
	public String getValue(String path) throws ConfigException {
		List<String> values = getValues(path);
		if (values == null || values.size() <= 0)
			return null;
		return values.get(0);
	}

	@Override
	public List<String> getValues(String path) throws ConfigException {
		if (path == null)
			throw new ConfigException("The path can not be null");

		if (!path.startsWith("/")) {
			if (currentPath != null && currentPath.length() != 0) {
				path = currentPath + '/' + path;
			} else {
				throw new ConfigException("incorrect path: " + path);
			}
		}
		
		Config config = interConfig;
		
		List<String> values = new LinkedList<String>();
		PathResolver resolver = new PathResolver();
		resolver.resolve(path);
		Token token = null;
		String filtName = null;
		
		while (resolver.next()) {
			token = resolver.getToken();
			switch (token.type) {
			case Token.TYPE.PATH_NAME:
				if (config.containsSubconfig(token.token)) {
					config = config.getSubconfig(token.token);
				} else {
					return null;
				}
			case Token.TYPE.EXPRESS_LEFT:
				filtName = token.token;
				break;
			case Token.TYPE.EXPRESS_RIGHT:
				if (config.contains(filtName)) {
					boolean flag = true;
					for (String val : config.getConfigItem(filtName).values) {
						if (val.equals(token.token)) {
							flag = false;
							break;
						}
					}
					if (flag) {
						return null;
					}
				} else {
					return null;
				}
				break;
			case Token.TYPE.VALUE_NAME:
				values.addAll(config.getConfigItem(filtName).values);
			}
		}
		return values;
	}

	@Override
	public List<String> getSubNames(String path) throws ConfigException {
		// TODO Auto-generated method stub
		return null;
	}

}
